﻿using System;
using System.Linq;
using System.Text;

namespace OpenAiMobile.Util.Io
{
    public static class IoHelper
    {
        /// <summary>字节数组转为Base64编码</summary>
        /// <param name="data"></param>
        /// <param name="offset"></param>
        /// <param name="count"></param>
        /// <param name="lineBreak">是否换行显示</param>
        /// <returns></returns>
        public static string ToBase64(this byte[] data, int offset = 0, int count = -1, bool lineBreak = false)
        {
            if (data == null || data.Length == 0)
            {
                return "";
            }

            if (count <= 0)
            {
                count = data.Length - offset;
            }
            else if (offset + count > data.Length)
            {
                count = data.Length - offset;
            }

            var options = lineBreak ? Base64FormattingOptions.InsertLineBreaks : Base64FormattingOptions.None;
            return Convert.ToBase64String(data, offset, count, options);
        }

        /// <summary>Base64字符串转为字节数组</summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public static byte[] ToBase64(this string data)
        {
            if (string.IsNullOrWhiteSpace(data))
            {
                return Array.Empty<byte>();
            }

            data = data.Trim();
            var str = data;
            if (str[str.Length - 1] != '=')
            {
                var num = data.Length % 4;
                if (num > 0)
                {
                    data += new string('=', 4 - num);
                }
            }

            data = data.Replace('-', '+').Replace('_', '/');
            return Convert.FromBase64String(data);
        }

        /// <summary>字节数组转换为字符串</summary>
        /// <param name="buf">字节数组</param>
        /// <param name="encoding">编码格式</param>
        /// <param name="offset">字节数组中的偏移</param>
        /// <param name="count">字节数组中的查找长度</param>
        /// <returns></returns>
        public static string ToStr(this byte[] buf, Encoding encoding = null, int offset = 0, int count = -1)
        {
            if (buf == null || buf.Length == 0 || offset >= buf.Length)
            {
                return null;
            }

            if (encoding == null)
            {
                encoding = Encoding.UTF8;
            }

            var num1 = buf.Length - offset;
            if (count < 0 || count > num1)
            {
                count = num1;
            }

            var num2 = 0;
            var preamble = encoding.GetPreamble();
            if (preamble.Length != 0 &&
                buf.Length >= offset + preamble.Length &&
                buf.Skip(offset).Take(preamble.Length).SequenceEqual(preamble))
            {
                num2 = preamble.Length;
            }

            return encoding.GetString(buf, offset + num2, count - num2);
        }

        /// <summary>向字节数组写入一片数据</summary>
        /// <param name="dst">目标数组</param>
        /// <param name="dstOffset">目标偏移</param>
        /// <param name="src">源数组</param>
        /// <param name="srcOffset">源数组偏移</param>
        /// <param name="count">数量</param>
        /// <returns>返回实际写入的字节个数</returns>
        public static int Write(this byte[] dst, int dstOffset, byte[] src, int srcOffset = 0, int count = -1)
        {
            if (count <= 0)
            {
                count = src.Length - srcOffset;
            }

            if (dstOffset + count > dst.Length)
            {
                count = dst.Length - dstOffset;
            }

            Buffer.BlockCopy(src, srcOffset, dst, dstOffset, count);
            return count;
        }
    }
}
